Quasar is a popular Vue UI library for developing good looking Vue apps.
In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.
File Upload Progress
We can add file upload progress display to the file picker with the q-file
component.
To do this, we write:
<!DOCTYPE html>
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
rel="stylesheet"
type="text/css"
/>
<link
href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
rel="stylesheet"
type="text/css"
/>
</head>
<body class="body--dark">
<script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
<div id="q-app">
<q-layout
view="lHh Lpr lFf"
container
style="height: 100vh;"
class="shadow-2 rounded-borders"
>
<div class="q-pa-md">
<q-file
:value="files"
@input="updateFiles"
label="Pick files"
outlined
multiple
:clearable="!isUploading"
style="max-width: 400px;"
>
<template v-slot:file="{ index, file }">
<q-chip
class="full-width q-my-xs"
:removable="isUploading && uploadProgress[index].percent < 1"
square
>
<q-linear-progress
class="absolute-full full-height"
:value="uploadProgress[index].percent"
:color="uploadProgress[index].color"
track-color="grey-2"
>
</q-linear-progress>
<q-avatar>
<q-icon :name="uploadProgress[index].icon"></q-icon>
</q-avatar>
<div class="ellipsis relative-position">
{{ file.name }}
</div>
<q-tooltip>
{{ file.name }}
</q-tooltip>
</q-chip>
</template>
<template v-slot:after v-if="canUpload">
<q-btn
color="primary"
dense
icon="cloud_upload"
round
@click="upload"
:disable="!canUpload"
:loading="isUploading"
>
</q-btn>
</template>
</q-file>
</div>
</q-layout>
</div>
<script>
new Vue({
el: "#q-app",
data: {
files: null,
uploadProgress: [],
uploading: null,
isUploading: false
},
computed: {
isUploading() {
return this.uploading !== null;
},
canUpload() {
return this.files !== null;
}
},
methods: {
updateFiles(files) {
this.files = files;
this.uploadProgress = (files || []).map((file) => ({
error: false,
color: "green-1",
percent: 0,
icon:
file.type.indexOf("video/") === 0
? "movie"
: file.type.indexOf("image/") === 0
? "photo"
: file.type.indexOf("audio/") === 0
? "audiotrack"
: "insert_drive_file"
}));
},
upload() {
clearTimeout(this.uploading);
const allDone = this.uploadProgress.every(
(progress) => progress.percent === 1
);
this.uploadProgress = this.uploadProgress.map((progress) => ({
...progress,
error: false,
color: "green-2",
percent: allDone === true ? 0 : progress.percent
}));
this.__updateUploadProgress();
},
__updateUploadProgress() {
let done = true;
this.uploadProgress = this.uploadProgress.map((progress) => {
if (progress.percent === 1 || progress.error === true) {
return progress;
}
const percent = Math.min(
1,
progress.percent + Math.random() / 10
);
const error = percent < 1 && Math.random() > 0.95;
if (error === false && percent < 1 && done === true) {
done = false;
}
return {
...progress,
error,
color: error === true ? "red-2" : "green-2",
percent
};
});
this.uploading =
done !== true
? setTimeout(this.__updateUploadProgress, 300)
: null;
}
},
beforeDestroy() {
clearTimeout(this.uploading);
}
});
</script>
</body>
</html>
We listen for file changes with the updateFiles
method.
In the method, we get the files from the parameter and then call map
to return an array of object to display the icons we want.
The upload
method is called when we click on the button on the right.
We get the progress from the uploadProgress
property and then update it by getting the progress from the progress.percent
property.
We set the percent from in the method and set the as the value of the value
prop in the q-linear-progress
component to display the progress.
Conclusion
We can add a progress bar to the file input to show file upload progress with Quasar.